package com.stylismo.intellij.inspection.groovy;

import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemHighlightType;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiModifierListOwner;
import com.stylismo.intellij.inspection.NullabilityAnnotationsInspection;
import com.stylismo.intellij.inspection.QuickFixFactory;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor;
import org.jetbrains.plugins.groovy.codeInspection.metrics.GroovyMethodParameterCountInspectionBase;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;

import javax.annotation.Nonnull;

/**
 * Name: GroovyAddPackageInfoWithNullabilityDefaultsVisitor<br>
 * User: Yao<br>
 * Date: 2017/11/5<br>
 * Time: 01:22<br>
 */
public class GroovyAddPackageInfoWithNullabilityDefaultsVisitor extends BaseInspectionVisitor {

    @Nonnull private final NullabilityAnnotationsInspection nullabilityAnnotationsInspection;

    public GroovyAddPackageInfoWithNullabilityDefaultsVisitor(NullabilityAnnotationsInspection nullabilityAnnotationsInspection) {

        this.nullabilityAnnotationsInspection = nullabilityAnnotationsInspection;
    }


    /**
     * @see GroovyMethodParameterCountInspectionBase.Visitor#visitMethod(org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod)
     */
    @Override
    public void visitMethod(@NotNull GrMethod method) {
        //下面的代码没必要 已经有 visitParameter 了
/*        PsiParameter[] parameters = method.getParameterList().getParameters();
        for (PsiParameter parameter : parameters) {
            if (nullabilityAnnotationsInspection.parameterNeedsAnnotation(parameter)) {

            }
        }*/

        super.visitMethod(method);
        if (nullabilityAnnotationsInspection.isMethodNeedAnnotation(method)) {
            this.registerError(method);
        }
    }

    @Override
    public void visitField(@NotNull GrField field) {
        super.visitField(field);
        if (nullabilityAnnotationsInspection.isFieldMissingNullAnnotation(field, field.getType())) {
            this.registerError(field);
        }
    }

    @Override
    public void visitParameter(@NotNull GrParameter parameter) {
        super.visitParameter(parameter);
        if (nullabilityAnnotationsInspection.parameterNeedsAnnotation(parameter)
                && !nullabilityAnnotationsInspection.hasAnnotation(parameter)) {
            this.registerError(parameter);
        }
    }

    @Override
    protected void registerError(@NotNull PsiElement location,
                                 @NotNull String description,
                                 @Nullable LocalQuickFix[] fixes,
                                 ProblemHighlightType highlightType) {
        super.registerError(location, description,
                location instanceof PsiModifierListOwner ?
                        QuickFixFactory.createQuickFixes((PsiModifierListOwner) location, nullabilityAnnotationsInspection.isRemoveRedundantAnnotations())
                        : fixes,
                highlightType);
    }

}
